using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.DirectoryServices;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Microsoft.ApplicationBlocks.Data;
using Microsoft.AceEngineering.SPM.SPMBusinessLayer;
using Microsoft.AceEngineering.SPM.SPMCustomDataEntity;

public partial class Admin_Users_Users : Page
{
    private static string VIEW = "view";
    private static string ADD = "add";
    private static string EDIT = "edit";

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Session["user"] == null)
            ValidateUser();
        else
        {
            UserCDE userData = (UserCDE)Session["user"];
            if (userData.Time.AddMinutes(Int32.Parse(ConfigurationManager.AppSettings["AbsoluteExpiration"].ToString())) <= DateTime.Now)
                ValidateUser();
        }

        bool isAdmin = UsersBL.GetUserAdmin(Session["loginname"].ToString());
        if (!isAdmin)
            Response.Redirect("~/Home.aspx");

        if (!Page.IsPostBack)
        {
            ViewState[VIEW] = ADD;
        }
    }

    private string GiveMeAlias(string domainAndAlias)
    {
        domainAndAlias = domainAndAlias.ToLower();
        char[] strSeperator = new char[] { '\\' };
        string[] aryAuthUser = new string[2];
        aryAuthUser = domainAndAlias.Split(strSeperator);
        return aryAuthUser[1];
    }

    private void ValidateUser()
    {
        string currAlias = GiveMeAlias(HttpContext.Current.User.Identity.Name);
        UserCDE user = UsersBL.ValidateUser(currAlias);
        if (user.Active)
        {
            Session["user"] = user;
            Session["loginname"] = user.UserAlias;
        }
        else
        {
            Response.Redirect(Request.ApplicationPath + "/Errors/NoAccess.htm");
        }
    }

    protected void lbnew_Click(object sender, EventArgs e)
    {
        pnlSearch.Visible = false;
        btnCancel.Visible = false;
        txtUserID.Text = null;
        pnlUser.Visible = true;
        txtUserAlias.Text = null;
        txtUserName.Text = null;
        txtUserEmail.Text = null;
        chkIsAdmin.Checked = false;
        chkActive.Checked = false;
        gridUserSearchEdit.Visible = false;
        btnFindUser.Visible = true;

        ViewState[VIEW] = ADD;

        editl.Attributes.Remove("class");
        addl.Attributes.Add("class", "active");
    }

    protected void lbedit_Click(object sender, EventArgs e)
    {
        pnlSearch.Visible = true;
        pnlUser.Visible = false;
        gridUserSearchEdit.Visible = false;

        btnCancel.Visible = true;
        btnSearch.Visible = true;
        btnGo.Visible = false;

        txtSearch.Text = null;
        lstUserNames.Visible = false;
        lblResult.Visible = false;
        btnFindUser.Visible = false;

        rdsearchType.SelectedIndex = 0;

        ViewState[VIEW] = EDIT;

        addl.Attributes.Remove("class");
        editl.Attributes.Add("class", "active");
    }

    protected void btnSearch_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            SearchResults(txtSearch.Text, Int32.Parse(rdsearchType.SelectedValue));
        }
        else
        {
            Page pge = (Page)this.Page;
            Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, "Server Side Validation Failed.", "errorkey");
        }

        addl.Attributes.Remove("class");
        editl.Attributes.Add("class", "active");
    }

    protected void SearchResults(string name, int sType)
    {
        DataView dv = UsersBL.dsSearchUser(name, sType).Tables[0].DefaultView;
        lstUserNames.DataSource = dv;
        lstUserNames.DataBind();

        if (dv.Count == 0)
        {
            lstUserNames.Visible = false;
            lblResult.Visible = false;
            btnGo.Visible = false;

            Page pge = (Page)this.Page;
            string strMsg = "No users found.";
            Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, strMsg, "errorkey");
        }
        else
        {
            lstUserNames.Visible = true;
            lblResult.Visible = true;
            btnGo.Visible = true;
        }

        dv.Dispose();
    }

    protected void GoClick(object sender, EventArgs e)
    {
        if (lstUserNames.SelectedIndex != -1)
        {
            GetUser(lstUserNames.SelectedItem.Value);

            pnlSearch.Visible = false;
            pnlUser.Visible = true;
        }
        else
        {
            Page pge = (Page)this.Page;
            Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, "No user was selected.", "errorkey");
            ViewState[VIEW] = EDIT;
        }

        addl.Attributes.Remove("class");
        editl.Attributes.Add("class", "active");
    }

    protected void GetUser(string strGUID)
    {
        DataView dv = UsersBL.dsSearchUserByGuid(strGUID).Tables[0].DefaultView;

        txtUserID.Text = dv[0].Row["UserGuid"].ToString();
        txtUserName.Text = dv[0].Row["UserName"].ToString();
        txtUserEmail.Text = dv[0].Row["UserEmail"].ToString();
        txtUserAlias.Text = dv[0].Row["UserAlias"].ToString();
        chkIsAdmin.Checked = Convert.ToBoolean(dv[0].Row["IsAdmin"].ToString());
        chkActive.Checked = Convert.ToBoolean(dv[0].Row["Active"].ToString());

        dv.Dispose();
    }

    protected void CancelClick(object source, EventArgs e)
    {
        pnlUser.Visible = false;
        pnlSearch.Visible = true;
        txtUserID.Text = null;

        addl.Attributes.Remove("class");
        editl.Attributes.Add("class", "active");
    }

    protected void SubmitClick(object source, EventArgs e)
    {
        if (Page.IsValid)
        {
            Guid gdUserID = new Guid();
            if (!string.IsNullOrEmpty(txtUserID.Text))
                gdUserID = new Guid(txtUserID.Text);
            else
                gdUserID = System.Guid.NewGuid();

            try
            {
                UsersBL.UpdateInsertUser(gdUserID, txtUserName.Text, txtUserAlias.Text, txtUserEmail.Text, chkIsAdmin.Checked, chkActive.Checked, Session["loginname"].ToString());

                if (ViewState[VIEW].ToString() == EDIT)
                {
                    pnlUser.Visible = false;
                    pnlSearch.Visible = true;
                    rdsearchType.SelectedIndex = 0;
                    btnGo.Visible = false;
                    lstUserNames.Visible = false;
                    lblResult.Visible = false;
                    txtUserID.Text = null;
                    txtSearch.Text = null;

                    addl.Attributes.Remove("class");
                    editl.Attributes.Add("class", "active");

                    Page pge = (Page)this.Page;
                    Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, "User updated successfully.", "updateuser");
                }
                if (ViewState[VIEW].ToString() == ADD)
                {
                    txtUserAlias.Text = null;
                    txtUserEmail.Text = null;
                    txtUserName.Text = null;
                    chkActive.Checked = false;
                    chkIsAdmin.Checked = false;

                    editl.Attributes.Remove("class");
                    addl.Attributes.Add("class", "active");

                    Page pge = (Page)this.Page;
                    Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, "User added successfully.", "adduser");
                    gridUserSearchEdit.Visible = false;
                }
            }
            catch (Exception ex)
            {
                string strErrorType = ex.Message.ToString().Substring(0, 8);

                if (strErrorType != "APMError")
                    throw ex;

                Page pge = (Page)this.Page;
                Microsoft.ACEEngineering.Utility.CommonProcess.APMErrorHandling(ex, Request.IsLocal, pge, Session, Request);

                if (ViewState[VIEW].ToString() == EDIT)
                {
                    addl.Attributes.Remove("class");
                    editl.Attributes.Add("class", "active");
                }
                if (ViewState[VIEW].ToString() == ADD)
                {
                    editl.Attributes.Remove("class");
                    addl.Attributes.Add("class", "active");
                }
            }
        }
        else
        {
            StringBuilder msg = new StringBuilder("Please correct the following:\\n");
            // Loop through all validation controls to see which
            // generated the errors.
            foreach (IValidator aValidator in this.Validators)
            {
                if (!aValidator.IsValid)
                {
                    msg.Append("- " + aValidator.ErrorMessage + "\\n");
                }
            }
            Page pge = (Page)this.Page;
            Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, msg.ToString(), "errorkey");

            if (ViewState[VIEW].ToString() == EDIT)
            {
                addl.Attributes.Remove("class");
                editl.Attributes.Add("class", "active");
            }
            else
            {
                editl.Attributes.Remove("class");
                addl.Attributes.Add("class", "active");
            }
        }
    }

    protected void FindUserClick(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            if (txtUserAlias.Text.Trim().ToString().Length >= 3)
            {
                string strAlias = txtUserAlias.Text.Trim().ToString();
                ViewState["txtUserAlias"] = strAlias;
                List<UserADData> userADData = LookupAlias(strAlias); // This will search all the users in the AD limited to specific count size.

                // Bind to the grid.    
                gridUserSearchEdit.Visible = true;
                gridUserSearchEdit.DataSource = userADData;
                gridUserSearchEdit.DataBind();

                txtUserName.Text = string.Empty;
                txtUserEmail.Text = string.Empty;
            }
            else
            {
                Page pge = (Page)this.Page;
                Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, "Please enter minimum of 3 characters to search in Active Directory.", "searchUser");
            }
        }
        else
        {
            StringBuilder msg = new StringBuilder("Please correct the following:\\n");
            foreach (IValidator aValidator in this.Validators)
            {
                if (!aValidator.IsValid)
                {
                    msg.Append("- " + aValidator.ErrorMessage + "\\n");
                }
            }
            Page pge = (Page)this.Page;
            Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, msg.ToString(), "errorkey");
        }
        if (ViewState[VIEW].ToString() == EDIT)
        {
            addl.Attributes.Remove("class");
            editl.Attributes.Add("class", "active");
        }
        else
        {
            editl.Attributes.Remove("class");
            addl.Attributes.Add("class", "active");
        }
    }


    /// <summary>
    /// This method is for extracting users from Active Directory.
    /// </summary>
    /// <param name="strAlias">The starting characters for search - alias.</param>
    /// <returns></returns>
    private List<UserADData> LookupAlias(string strAlias)
    {
        string strUserName;
        string strDomain;
        string[] aryAuthUser = new string[2];
        DirectoryEntry ent = null;
        DirectorySearcher search = null;
        List<UserADData> attList = null;

        try
        {

            if (string.IsNullOrEmpty(strAlias))
                throw new Exception("Error: Missing Lookup Alias.");            

            strUserName = User.Identity.Name;
            strUserName = strUserName.ToLower();

            char[] strSeperator = new char[] { '\\' };

            string namedata = strUserName;
            aryAuthUser = namedata.Split(strSeperator);
            strDomain = aryAuthUser[0];
            strUserName = aryAuthUser[1];

            string LDAPConnectionPath = "";
            LDAPConnectionPath = "LDAP://" + strDomain.Trim().ToLower();

            attList = new List<UserADData>();
            ent = new DirectoryEntry(LDAPConnectionPath);
            search = new DirectorySearcher(ent);
            // Define the filter for search.
            search.Filter = "(&(objectClass=person)(objectClass=user)(!objectClass=computer)(sAMAccountName=" + strAlias + "*))";

            search.PropertiesToLoad.Add("mail");
            search.PropertiesToLoad.Add("cn");
            search.PropertiesToLoad.Add("sAMAccountName");
            search.PropertiesToLoad.Add("displayName");
            // This is max records searched from AD. 
            search.SizeLimit = Int32.Parse(ConfigurationManager.AppSettings["pageSizeforAD"].Trim().ToString());

            // The call to FindAll() method will result in searching the AD for the users.
            SearchResultCollection resultCollection = search.FindAll();
            int ncount = resultCollection.Count;

            UserADData userInstance = null;
            if (null != resultCollection)
            {
                for (int i = 0; i < resultCollection.Count; i++)
                {
                    if (null != resultCollection[i].Properties["mail"] && resultCollection[i].Properties["mail"].Count != 0)
                    {
                        userInstance = new UserADData();

                        if (null != resultCollection[i].Properties["mail"] && resultCollection[i].Properties["mail"].Count != 0)
                            userInstance.Email = (string)resultCollection[i].GetDirectoryEntry().Properties["mail"].Value;
                        if (null != resultCollection[i].Properties["sAMAccountName"] && resultCollection[i].Properties["sAMAccountName"].Count != 0 && null != resultCollection[i].Properties["mail"] && resultCollection[i].Properties["mail"].Count != 0)
                            userInstance.Alias = (string)resultCollection[i].GetDirectoryEntry().Properties["sAMAccountName"].Value;
                        if (null != resultCollection[i].Properties["displayName"] && resultCollection[i].Properties["displayName"].Count != 0 && null != resultCollection[i].Properties["mail"] && resultCollection[i].Properties["mail"].Count != 0)
                            userInstance.Name = (string)resultCollection[i].GetDirectoryEntry().Properties["displayName"].Value;

                        attList.Add(userInstance);
                        userInstance = null;
                    }
                }
            }
        }
        catch (Exception error)
        {
            attList = null;
            // Display the message to the user that an error happened while accessing the AD.
            Page pge = (Page)this.Page;
            Microsoft.ACEEngineering.Utility.CommonProcess.CreateMessageAlert(ref pge, "Error: Unknown error, while searching the users in Active Directory.", "errorkey");

            Server.ClearError();
        }
        finally
        {
            if (ent != null)
                ent.Dispose();

            if (search != null)
                search.Dispose();
        }
        return attList;
    }

    protected void gridUserSearchEdit_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName.Equals("select"))
        {
            int index = Convert.ToInt32(e.CommandArgument);
            // Set user Alias.
            string userAlias = gridUserSearchEdit.DataKeys[index].Value.ToString().Trim();
            // Set Display Name.
            string name = gridUserSearchEdit.Rows[index].Cells[1].Text.Trim();
            // Set email Address.
            string email = gridUserSearchEdit.Rows[index].Cells[2].Text.Trim();

            txtUserAlias.Text = userAlias;
            txtUserEmail.Text = email;
            txtUserName.Text = name;
        }
    }

    protected void gridUserSearchEdit_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        txtUserAlias.Text = ViewState["txtUserAlias"].ToString();
        List<UserADData> userADData = LookupAlias(ViewState["txtUserAlias"].ToString()); // This will search all the users in the AD limited to specific count size.

        // The new page index is set.
        gridUserSearchEdit.PageIndex = e.NewPageIndex;
        // Bind to the grid.    
        gridUserSearchEdit.Visible = true;
        gridUserSearchEdit.DataSource = userADData;
        gridUserSearchEdit.DataBind();
    }
}
